package com.pioneer.web.purchase.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pioneer.common.constant.PurchaseConstants;
import com.pioneer.common.exception.CustomException;
import com.pioneer.common.utils.SecurityUtils;
import com.pioneer.web.purchase.domain.PurOrder;
import com.pioneer.web.purchase.domain.PurOrderBody;
import com.pioneer.web.purchase.domain.PurPlan;
import com.pioneer.web.purchase.domain.PurPlanBody;
import com.pioneer.web.purchase.mapper.PurOrderBodyMapper;
import com.pioneer.web.purchase.mapper.PurOrderMapper;
import com.pioneer.web.purchase.mapper.PurPlanBodyMapper;
import com.pioneer.web.purchase.service.IPurOrderService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * PurOrderServiceImpl
 *
 * @author hlm
 * @date 2025-04-02 14:22:51
 */
@Service
public class PurOrderServiceImpl extends ServiceImpl<PurOrderMapper, PurOrder> implements IPurOrderService {

    @Resource
    private PurOrderBodyMapper orderBodyMapper;

    @Resource
    private PurPlanBodyMapper planBodyMapper;

    @Override
    public String genOrderByPlan(PurPlan plan) {
        // 保存采购订单
        PurOrder purOrder = new PurOrder();
        purOrder.setOrderCode(genOrderCode());
        purOrder.setOrderName(plan.getPlanName() + "-采购订单");
        purOrder.setSourceId(plan.getPlanId());
        purOrder.setTotal(plan.getTotal());
        purOrder.setApproveStatus("0");
        purOrder.setIsIn(PurchaseConstants.ORDER_NOT_IN);
        boolean ret = save(purOrder);
        if (!ret) {
            return "保存采购订单失败";
        }
        List<PurPlanBody> planBodyList = plan.getPlanBodyList();
        if (CollUtil.isEmpty(planBodyList)) {
            return "采购计划单子表信息不能为空";
        }
        // 保存采购订单子表
        List<PurOrderBody> orderBodyList = new ArrayList<>();
        for (PurPlanBody planBody : planBodyList) {
            PurOrderBody orderBody = new PurOrderBody();
            orderBody.setOrderId(purOrder.getOrderId());
            orderBody.setSourceRowid(planBody.getPlanBodyId());
            orderBody.setDeptId(planBody.getDeptId());
            orderBody.setInventoryId(planBody.getInventoryId());
            orderBody.setPurNumber(planBody.getPlanPurNumber());
            orderBody.setPurPrice(planBody.getPlanPrice());
            orderBody.setPurTotal(planBody.getPlanTotal());
            orderBodyList.add(orderBody);
        }
        int result = orderBodyMapper.insertBatch(orderBodyList);
        if (result <= 0) {
            return "保存采购订单子表失败";
        }
        return null;
    }

    @Override
    public String delOrderByPlan(PurPlan plan) {
        // 根据采购计划ID查询采购订单
        LambdaQueryWrapper<PurOrder> query = Wrappers.lambdaQuery();
        query.eq(PurOrder::getSourceId, plan.getPlanId());
        PurOrder order = getOne(query);
        if (order == null) {
            return null;
        }
        if (!"0".equals(order.getApproveStatus())) {
            return "下游单据已提交或审批，不允许弃审";
        }
        // 根据采购订单ID查询采购订单子表信息
        LambdaQueryWrapper<PurOrderBody> bodyQuery = Wrappers.lambdaQuery();
        bodyQuery.eq(PurOrderBody::getOrderId, order.getOrderId());
        List<PurOrderBody> orderBodyList = orderBodyMapper.selectList(bodyQuery);
        // 过滤ID集合
        List<Long> orderBodyIdList = orderBodyList.stream().map(PurOrderBody::getOrderBodyId).toList();
        // 根据ID集合批量删除子表信息
        int bodyRet = orderBodyMapper.deleteByIds(orderBodyIdList);
        if (bodyRet <= 0) {
            return "删除下游单据[采购订单子表]失败";
        }
        // 删除采购订单
        boolean ret = removeById(order);
        if (!ret) {
            return "删除下游单据[采购订单失败]";
        }
        return null;
    }

    @Override
    public PurOrder selectOrderById(Long orderId) {
        // 根据采购订单ID查询采购订单 select * from pur_order where order_id = #{orderId}
        PurOrder purOrder = getById(orderId);
        // 根据采购订单ID查询采购订单子表信息 select * from pur_order_body where order_id = #{orderId}
        LambdaQueryWrapper<PurOrderBody> query = Wrappers.lambdaQuery();
        query.eq(PurOrderBody::getOrderId, orderId);
        List<PurOrderBody> orderBodyList = orderBodyMapper.selectList(query);
        purOrder.setOrderBodyList(orderBodyList);
        // 返回
        return purOrder;
    }

    @Override
    public boolean updateOrder(PurOrder order) {
        // 校验订单状态
        PurOrder purOrder = getById(order.getOrderId());
        if (purOrder == null) {
            throw new CustomException("采购订单不存在，请刷新后重试");
        }
        if (!"0".equals(purOrder.getApproveStatus())) {
            throw new CustomException("只有订单状态为初始的数据才可以修改");
        }
        // 修改采购订单子表
        List<PurOrderBody> orderBodyList = order.getOrderBodyList();
        if (CollUtil.isEmpty(orderBodyList)) {
            throw new CustomException("采购订单子表信息不能为空");
        }
        // 获取来源单据行ID集合
        List<Long> planBodyIdList = orderBodyList.stream().map(PurOrderBody::getSourceRowid).toList();
        // 根据来源单据行ID集合查询采购计划子表信息
        List<PurPlanBody> purPlanBodyList = planBodyMapper.selectBatchIds(planBodyIdList);
        if (CollUtil.isEmpty(purPlanBodyList)) {
            throw new CustomException("来源单据的[采购计划子表]信息为空，请检查");
        }
        // 总额
        BigDecimal total = BigDecimal.ZERO;
        // 循环采购订单子表
        for (int i = 0; i < orderBodyList.size(); i++) {
            PurOrderBody orderBody = orderBodyList.get(i);
            if (ObjectUtil.isNull(orderBody.getOrderBodyId())) {
                throw new CustomException("参数缺失，采购订单子表ID不能为空");
            }
            if (ObjectUtil.isNull(orderBody.getSupplierId())) {
                throw new CustomException("第" + (i + 1) + "行的供应商不能为空");
            }
            BigDecimal purPrice = orderBody.getPurPrice();
            if (purPrice == null || purPrice.doubleValue() < 0) {
                throw new CustomException("第" + (i + 1) + "行的采购单价必须大于等于0");
            }
            purPlanBodyList.stream().filter(b -> b.getPlanBodyId().equals(orderBody.getSourceRowid())).findFirst().ifPresent(b -> {
                orderBody.setPurTotal(b.getPlanPurNumber().multiply(orderBody.getPurPrice()));
            });
            if (orderBody.getPurTotal() == null || orderBody.getPurTotal().doubleValue() < 0) {
                throw new CustomException("第" + (i + 1) + "行的采购总价必须大于等于0");
            }
            // 实例化一个新的采购订单子表
            PurOrderBody updateOrderBody = new PurOrderBody();
            updateOrderBody.setOrderBodyId(orderBody.getOrderBodyId());
            updateOrderBody.setSupplierId(orderBody.getSupplierId());
            updateOrderBody.setPurPrice(orderBody.getPurPrice());
            updateOrderBody.setPurTotal(orderBody.getPurTotal());
            // 计算总额
            total = total.add(updateOrderBody.getPurTotal());
            // 修改采购订单子表信息
            int ret = orderBodyMapper.updateById(updateOrderBody);
            if (ret <= 0) {
                throw new CustomException("修改采购订单子表失败");
            }
        }
        // 修改采购订单
        PurOrder updateOrder = new PurOrder();
        updateOrder.setOrderId(order.getOrderId());
        updateOrder.setOrderName(order.getOrderName());
        updateOrder.setTotal(total);
        return updateById(updateOrder);
    }

    @Override
    public boolean commitOrder(PurOrder order) {
        // 根据采购订单ID查询详细信息
        PurOrder purOrder = selectOrderById(order.getOrderId());
        // 校验采购订单
        if (purOrder == null) {
            throw new CustomException("采购订单不存在，请刷新后重试");
        }
        // 校验采购状态
        if (!"0".equals(purOrder.getApproveStatus())) {
            throw new CustomException("只有订单状态为初始的数据才可以提交");
        }
        // 获取采购订单子表信息
        List<PurOrderBody> orderBodyList = purOrder.getOrderBodyList();
        // 校验采购订单子表信息
        if (CollUtil.isEmpty(orderBodyList)) {
            throw new CustomException("采购订单子信息不能为空，请检查");
        }
        for (int i = 0; i < orderBodyList.size(); i++) {
            PurOrderBody orderBody = orderBodyList.get(i);
            // 校验供应商
            if (ObjectUtil.isNull(orderBody.getSupplierId())) {
                throw new CustomException("第" + (i + 1) + "行的供应商不能为空，请先执行修改操作");
            }
            // 校验采购单价
            BigDecimal purPrice = orderBody.getPurPrice();
            if (purPrice == null || purPrice.doubleValue() < 0) {
                throw new CustomException("第" + (i + 1) + "行的采购单价必须大于等于0");
            }
        }
        // 修改采购订单状态 update pur_order set approve_status = '1' where order_id = ?
        PurOrder updateOrder = new PurOrder();
        updateOrder.setOrderId(order.getOrderId());
        updateOrder.setApproveStatus("1");
        return updateById(updateOrder);
    }

    @Override
    public boolean approveOrder(PurOrder order) {
        PurOrder purOrder = selectOrderById(order.getOrderId());
        // 校验采购订单
        if (purOrder == null) {
            throw new CustomException("采购订不存在，请刷新后重试");
        }
        // 校验采购状态
        if (!"1".equals(purOrder.getApproveStatus())) {
            throw new CustomException("只有计划状态为初始的数据才可以审批");
        }
        // 修改采购订单
        PurOrder approveOrder = new PurOrder();
        approveOrder.setOrderId(order.getOrderId());
        approveOrder.setApprover(SecurityUtils.getLoginUser().getUsername());
        approveOrder.setApproveTime(LocalDateTime.now());
        approveOrder.setApproveOpinion(order.getApproveOpinion());
        String approveResult = order.getApproveResult();
        switch (approveResult) {
            case "pass" -> {
                // 将计划状态改为审批通过
                approveOrder.setApproveStatus("2");
            }
            case "notPass" -> {
                // 校验审批意见
                String approveOpinion = order.getApproveOpinion();
                if (StrUtil.isBlank(approveOpinion)) {
                    throw new CustomException("审批意见不能为空");
                }
                // 将计划状态改为审批不通过
                approveOrder.setApproveStatus("3");
            }
            case "reject" -> {
                // 校验审批意见
                String approveOpinion = order.getApproveOpinion();
                if (StrUtil.isBlank(approveOpinion)) {
                    throw new CustomException("审批意见不能为空");
                }
                // 将计划状态改为初始
                approveOrder.setApproveStatus("0");
            }
        }
        return updateById(approveOrder);
    }

    /**
     * 生成采购订单编号
     * @return 结果
     */
    private String genOrderCode() {
        // 根据指定格式获取当天字符串
        String today = DateUtil.format(new Date(), "yyyyMMdd");
        // 查询当天最大流水号记录
        String maxCode = getBaseMapper().selectMaxCode(today);
        if (StrUtil.isBlank(maxCode)) {
            // 当天没有流水号，直接返回
            return "ORDER" + today + "001";
        } else {
            // 截取最后三位
            String oldCode = maxCode.substring(maxCode.length() - 3);
            // 流水号+1并补0
            String newCode = String.format("%03d", Integer.parseInt(oldCode) + 1);
            // 返回新的流水号
            return "ORDER" + today + newCode;
        }
    }
}
